package controller

import (
	"CampusCloudAid/dao/mysql"
	"CampusCloudAid/logic"
	"CampusCloudAid/models"
	util "CampusCloudAid/pkg/captchaStore"
	"CampusCloudAid/pkg/jwt"
	"errors"

	"net/http"
	"strings"

	"github.com/gin-gonic/gin/binding"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
)

// Login 用户登录
// @Summary 用户登录接口
// @Produce json
// @Description 用户登录接口
// @Tags 用户相关接口
// @Param data body models.ParamLogin true "data"
// @Success 200 {object} ResponseData
// @router /api/v1/login [post]
func Login(ctx *gin.Context) {
	p := new(models.ParamLogin)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		zap.L().Error("models.ParamLogin BindJSON(p) failed", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(ctx, CodeServerBusy)
			return
		}
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": removeTopStruct(errs.Translate(trans)),
		})
		return
	}
	user, err := logic.Login(p)
	if err != nil {
		zap.L().Error("controller logic.Login(p) failed", zap.Error(err))
		if errors.Is(err, mysql.ErrUserNotExist) {
			ResponseError(ctx, CodeUserPhoneOrEmailNotExist)
			return
		} else if errors.Is(err, mysql.ErrInvalidPassword) {
			ResponseError(ctx, CodeInvalidPassword)
			return
		}
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, user)
}

// Register 处理注册请求的函数
// @Summary 用户注册接口
// @Description 用户注册请求接口,包含参数校验，逻辑处理和返回响应
// @Tags 用户相关接口
// @Accept application/json
// @Produce application/json
// @Param object body models.ParamSignUp true "注册参数"
// @Success 200 {object} ResponseData
// @Router /api/v1/register [post]
func Register(ctx *gin.Context) {
	p := new(models.ParamSignUp)
	if err := ctx.ShouldBindWith(p, binding.JSON); err != nil {
		zap.L().Error("ctx.ShouldBindWith(p, binding.JSON) failed", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(ctx, CodeServerBusy)
			return
		}
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg": removeTopStruct(errs.Translate(trans)),
		})
		return
	}

	// 验证码是否过期
	code := util.RedisStore{}.Get(p.IdKey, true)
	if len(code) == 0 {
		ResponseError(ctx, CodeCaptchaExpired)
		return
	}
	// 校验验证码
	verifyRes := logic.CaptVerify(p.IdKey, p.Captcha)
	if !verifyRes {
		ResponseError(ctx, CodeCaptchaError)
		return
	}
	// 验证码已经正确使用一次，删除验证码或标记为已使用
	//p.IdKey = util.RedisStore{}.Delete(p.IdKey)
	if err := logic.Register(p); err != nil {
		zap.L().Error("logic.Register(p) failed", zap.Error(err))
		if errors.Is(err, mysql.ErrUserExist) {
			ResponseError(ctx, CodeUserExist)
			return
		} else if errors.Is(err, mysql.ErrUserPhoneExist) {
			ResponseError(ctx, CodeUserPhoneExist)
			return
		}
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, CodeSuccess)
}

// GetUserInfo 使用id来查看个人信息
// @Summary 获取用户信息
// @Description 根据用户ID获取用户信息
// @Tags 用户相关接口
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer {token}"
// @Success 200 {object} ResponseData
// @Router /api/v1/user [get]
func GetUserInfo(ctx *gin.Context) {
	userId, err := jwt.GetUserId(ctx) //从token中获取此时的用户uid，然后查询数据库并返回给前端；
	if err != nil {
		zap.L().Error("从token查询用户失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	userInfo, err := logic.GetUserInfoByID(userId)
	if err != nil {
		zap.L().Error("查询用户信息逻辑错误 failed", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	ResponseSuccess(ctx, userInfo)

}

// UpdateUserInfo 更新个人信息
// @Summary 更新个人信息
// @Description 根据用户ID更新用户的个人信息
// @Tags 用户相关接口
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer {token}"
// @Security ApiKeyAuth
// @Param updateInfo body object false "用户信息更新参数，JSON格式"
// @Success 200 {object} ResponseData
// @Router /api/v1/user [post]
func UpdateUserInfo(ctx *gin.Context) {
	// 获取用户ID
	userId, err := jwt.GetUserId(ctx)
	//fmt.Println(userId)
	if err != nil {
		zap.L().Error("从token查询用户失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}

	// 解析请求中的参数
	var reqParam map[string]interface{} //传入修改的参数
	if err := ctx.ShouldBindJSON(&reqParam); err != nil {
		zap.L().Error("解析请求参数失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	// 判断邮箱字段是否被修改，并且检查是否包含 @ 符号
	if email, ok := reqParam["email"].(string); ok && email != "" && !strings.Contains(email, "@") {
		zap.L().Error("邮箱字段格式不正确")
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	//判断昵称是否合法
	if nickname, ok := reqParam["nickname"].(string); ok && nickname != "" {
		if len(nickname) < 5 || len(nickname) > 16 {
			zap.L().Error("昵称字段长度不符合要求")
			ResponseError(ctx, CodeInvalidParams)
			return
		}
	}
	if phone, ok := reqParam["phone"].(string); ok && phone != "" {
		if len(phone) != 11 {
			zap.L().Error("长度不符合要求")
			ResponseError(ctx, CodeInvalidParams)
			return
		}
	}
	// 更新用户信息
	if err = logic.UpdateUserInfo(userId, reqParam); err != nil {
		zap.L().Error("更新用户信息失败：", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}

	// 返回成功响应
	ResponseSuccess(ctx, nil)
}

// UpdateUserAvatar 更新用户头像
// @Summary 更新用户头像
// @Description 根据用户ID更新用户的头像
// @Tags 用户相关接口
// @Accept multipart/form-data
// @Produce json
// @Param Authorization header string true "Bearer {token}"
// @Security ApiKeyAuth
// @Param avatar formData file true "用户头像文件"
// @Success 200 {object} ResponseData
// @Router /api/v1/user/avatar [post]
func UpdateUserAvatar(ctx *gin.Context) {
	userId, err := jwt.GetUserId(ctx)
	file, err := ctx.FormFile("avatar")
	if err != nil {
		// 处理文件上传失败的情况
		zap.L().Error("头像上传失败：", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	avatar, err := logic.SaveUserAvatar(userId, file) //此时avatar是string类型的；
	if err != nil {
		zap.L().Error("保存用户头像失败：", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	if err = logic.UpdateUserAvatar(userId, avatar); err != nil { //
		zap.L().Error("更新用户头像失败：", zap.Error(err))
		ResponseError(ctx, CodeServerBusy)
		return
	}
	ResponseSuccess(ctx, avatar)
}

// GetReceivedOrders 获取显示用户接收到单子
// @Summary 获取用户接收到的订单
// @Description 获取用户接收到的订单列表
// @Tags 用户相关接口
// @Accept json
// @Produce json
// @Param Authorization header string true "Bearer {token}"
// @Security ApiKeyAuth
// @Success 200 {array} ResponseData
// @Router /api/v1/tasks/received [get]
func GetReceivedOrders(ctx *gin.Context) {
	userId, err := jwt.GetUserId(ctx)

	if err != nil {
		zap.L().Error("从token查询用户失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	tasks, err := logic.ReceivedTasksByUserId(userId)
	if err != nil {
		zap.L().Error("查询订单失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}

	ResponseSuccess(ctx, tasks)
}

// GetCreatedTasks 获取显示用户创建的订单
// @Summary 获取用户创建的任务
// @Description 获取用户创建的任务列表
// @Tags 用户相关接口
// @Param Authorization header string true "Bearer {token}"
// @Security ApiKeyAuth
// @Accept json
// @Produce json
// @Success 200 {array} ResponseData
// @Router /api/v1/tasks/created [get]
func GetCreatedTasks(ctx *gin.Context) {
	userId, err := jwt.GetUserId(ctx)
	if err != nil {
		zap.L().Error("从token查询用户失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}
	tasks, err := logic.CreatedTasksByUserId(userId)
	if err != nil {
		zap.L().Error("查询订单失败：", zap.Error(err))
		ResponseError(ctx, CodeInvalidParams)
		return
	}

	ResponseSuccess(ctx, tasks)
}
